package com.mindata.blockchain.socket.handler.server.block;

import com.mindata.blockchain.ApplicationContextProvider;
import com.mindata.blockchain.block.block.Block;
import com.mindata.blockchain.block.check.CheckerManager;
import com.mindata.blockchain.common.CommonUtil;
import com.mindata.blockchain.socket.base.AbstractBlockHandler;
import com.mindata.blockchain.socket.body.rpc.RpcBlockBody;
import com.mindata.blockchain.socket.body.rpc.RpcCheckBlockBody;
import com.mindata.blockchain.socket.common.queue.IntroAddBlockQueue;
import com.mindata.blockchain.socket.packet.BlockPacket;
import com.mindata.blockchain.socket.common.msg.MsgType;
import com.mindata.blockchain.socket.pbft.msg.VotePreMsg;
import com.mindata.blockchain.socket.common.queue.base.MsgQueueManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.ChannelContext;

/**
 * 收到请求生成区块消息，进入PrePre队列
 *
 * @author wuweifeng wrote on 2018/3/12.
 */
public class GenerateBlockRequestHandler extends AbstractBlockHandler<RpcBlockBody> {
    private Logger logger = LoggerFactory.getLogger(GenerateBlockRequestHandler.class);
    private IntroAddBlockQueue introAddBlockQueue = ApplicationContextProvider.getBean(IntroAddBlockQueue.class);


    @Override
    public Class<RpcBlockBody> bodyClass() {
        return RpcBlockBody.class;
    }

    @Override
    public Object handler(BlockPacket packet, RpcBlockBody rpcBlockBody, ChannelContext channelContext) {
        Block block = rpcBlockBody.getBlock();
        if (introAddBlockQueue.blockConcurrentHashMap.containsKey(block.getBlockHeader().getNumber())) {
            return null;
        }
        logger.info("收到来自于<{}><请求生成Block>消息，block信息为[{}]", rpcBlockBody.getAppId(), block.getHash());

        CheckerManager checkerManager = ApplicationContextProvider.getBean(CheckerManager.class);
        //对区块的基本信息进行校验，校验通过后进入pbft的Pre队列
        RpcCheckBlockBody rpcCheckBlockBody = checkerManager.check(block);
//        logger.info("校验结果:{}" , rpcCheckBlockBody);
        if (rpcCheckBlockBody.getCode() == 0) {
            VotePreMsg votePreMsg = new VotePreMsg();
            votePreMsg.setBlock(block);
            votePreMsg.setVoteType(MsgType.PREPREPARE);
            votePreMsg.setNumber(block.getBlockHeader().getNumber());
            votePreMsg.setAppId(rpcBlockBody.getAppId());
            votePreMsg.setHash(block.getHash());
            votePreMsg.setAgree(true);
            //将消息推入PrePrepare队列
            long cur = CommonUtil.getNow();
            logger.error("出块时间: {}",cur);
            ApplicationContextProvider.getBean(MsgQueueManager.class).pushMsg(votePreMsg);
        }

        return null;
    }
}
